package apus.application;

import apus.command.ExitCommand;
import apus.command.account.*;
import apus.command.call.AddCallCommand;
import apus.command.call.RemoveCallCommand;
import apus.command.call.ViewCallListCommand;
import apus.command.organization.AddOrganizationCommand;
import apus.command.organization.RemoveOrganizationCommand;
import apus.command.organization.UpdateOrganizationCommand;
import apus.command.organization.ViewOrganizationListCommand;
import apus.command.period.AddPeriodCommand;
import apus.command.period.RemovePeriodCommand;
import apus.command.period.ViewPeriodListCommand;
import apus.command.person.AddPersonCommand;
import apus.command.person.RemovePersonCommand;
import apus.command.person.UpdatePersonCommand;
import apus.command.person.ViewPersonListCommand;
import apus.command.phonenumber.*;
import apus.exception.BusinessException;
import apus.menu.Menu;
import apus.persistence.*;
import apus.persistence.jdbc.JdbcDAOFactory;
import apus.services.ServiceLocator;
import java.io.*;
import java.text.ParseException;

public class APUS_1 {
    
    private DaoFactory daoFactory;
    private Menu currentMenu;
    private Menu mainMenu;

    public void setFactory(DaoFactory factory) {
        this.daoFactory = factory;
    }

    public Menu getCurrentMenu() {
        return currentMenu;
    }

    public void setCurrentMenu(Menu menu) {
        currentMenu = menu;
    }

    public Menu getMainMenu() {
        return mainMenu;
    }
    

        
    

    public void init() throws ParseException, IOException {
        
        ServiceLocator.registerService(PersonDAO.class, daoFactory.getPersonDAO());
        ServiceLocator.registerService(PeriodDAO.class, daoFactory.getPeriodDAO());
        ServiceLocator.registerService(OrganizationDAO.class, daoFactory.getOrganizationDAO());
        ServiceLocator.registerService(AccountDAO.class, daoFactory.getAccountDAO());
        ServiceLocator.registerService(PhoneNumberDAO.class, daoFactory.getPhoneNumberDAO());
        ServiceLocator.registerService(CallDAO.class, daoFactory.getCallDAO());
        ServiceLocator.registerService(AccountDAO.class, daoFactory.getAccountDAO());
        ServiceLocator.registerService(UserDAO.class, daoFactory.getUserDAO());

    /*
        PeriodDAO periodDAO = ServiceLocator.getService(PeriodDAO.class);
        PersonDAO personDAO = ServiceLocator.getService(PersonDAO.class);
        OrganizationDAO organizationDAO = ServiceLocator.getService(OrganizationDAO.class);
        CallDAO callDAO = ServiceLocator.getService(CallDAO.class);
        PhoneNumberDAO phoneNumberDAO = ServiceLocator.getService(PhoneNumberDAO.class);
        AccountDAO accountDAO = ServiceLocator.getService(AccountDAO.class);
        
        
        periodDAO.create(new RealPeriod("10.11.2011", "16.12.2011"));
        periodDAO.create(new RealPeriod("15.11.2011", "26.12.2011"));
        periodDAO.create(new RealPeriod("20.06.2012", "20.07.2012"));
        periodDAO.create(new RealPeriod("10.02.2012", "16.03.2012"));
        //5
        personDAO.create(new RealPerson("John White"));
        personDAO.create(new RealPerson("Jack Black"));
        personDAO.create(new RealPerson("Bill Yellow"));
        personDAO.create(new RealPerson("Mike Brown"));
        personDAO.create(new RealPerson("Jane Blue"));
        personDAO.create(new RealPerson("Josef Black"));
        personDAO.create(new RealPerson("Mary Green"));
        personDAO.create(new RealPerson("Rick Pink"));
        //13
        organizationDAO.create(new RealOrganization("Cemetary"));
        organizationDAO.create(new RealOrganization("Factory"));
        organizationDAO.create(new RealOrganization("Beltelekom"));
        organizationDAO.create(new RealOrganization("Vitebsk public toilets"));
        
        //17
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(5), "1111111"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(6), "2222222"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(7), "3333333"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(8), "4444444"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(9), "5555555"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(10), "6666666"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(11), "7777777"));
        phoneNumberDAO.create(new RealPhoneNumber(personDAO.read(12), "8888888"));
        phoneNumberDAO.create(new RealPhoneNumber(organizationDAO.read(13), "1234567"));
        phoneNumberDAO.create(new RealPhoneNumber(organizationDAO.read(14), "7654321"));
        phoneNumberDAO.create(new RealPhoneNumber(organizationDAO.read(15), "1234321"));
        phoneNumberDAO.create(new RealPhoneNumber(organizationDAO.read(16), "8765678"));
        

        //29
        callDAO.create(new RealCall(phoneNumberDAO.read(17),phoneNumberDAO.read(18),13,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(19),phoneNumberDAO.read(18),3,"13.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(22),phoneNumberDAO.read(19),5,"13.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(18),phoneNumberDAO.read(22),8,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(20),phoneNumberDAO.read(18),2,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(25),phoneNumberDAO.read(25),7,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(26),phoneNumberDAO.read(21),13,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(18),phoneNumberDAO.read(19),14,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(22),phoneNumberDAO.read(27),17,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(27),phoneNumberDAO.read(20),3,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(22),phoneNumberDAO.read(18),1,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(24),phoneNumberDAO.read(28),3,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(27),phoneNumberDAO.read(25),7,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(18),phoneNumberDAO.read(19),9,"12.02.2012 12:34:55"));
        callDAO.create(new RealCall(phoneNumberDAO.read(22),phoneNumberDAO.read(20),5,"12.02.2012 12:34:55"));
        
        //44
        accountDAO.create(new RealAccount(personDAO.read(6),periodDAO.read(4)));
        accountDAO.create(new RealAccount(organizationDAO.read(14),periodDAO.read(4)));
        accountDAO.create(new RealAccount(personDAO.read(11),periodDAO.read(4)));
        accountDAO.create(new RealAccount(organizationDAO.read(13),periodDAO.read(4)));
        accountDAO.create(new RealAccount(personDAO.read(12),periodDAO.read(4)));
        accountDAO.create(new RealAccount(organizationDAO.read(15),periodDAO.read(4)));
        */
        
        //  Main menu initialization
        mainMenu = new Menu("Main menu");
        
        //  Submenu initialization
        Menu personSubMenu = new Menu("Person");
        Menu organizationSubMenu = new Menu("Organization");
        Menu accountSubMenu = new Menu("Account");
        Menu phoneNumberSubMenu = new Menu("Phone number");
        Menu periodSubMenu = new Menu("Period");
        Menu callSubMenu = new Menu("Call");
       
        //  Add the command
        mainMenu.addCommand(personSubMenu);
        mainMenu.addCommand(organizationSubMenu);
        mainMenu.addCommand(accountSubMenu);
        mainMenu.addCommand(phoneNumberSubMenu);
        mainMenu.addCommand(periodSubMenu);
        mainMenu.addCommand(callSubMenu);
        mainMenu.addCommand(new ExitCommand());
        
        //  Set current menu
        currentMenu=mainMenu;
        Menu.setMainMenu(mainMenu);
        Menu.setCurrentMenu(currentMenu);
        
        
        //  Phone number submenu commands
        phoneNumberSubMenu.addCommand(AddPhoneNumberCommand.getAddPhoneNumberToPersonCommand());
        phoneNumberSubMenu.addCommand(AddPhoneNumberCommand.getAddPhoneNumberToOrganizationCommand());
        phoneNumberSubMenu.addCommand(new RemovePhoneNumberCommand());
        phoneNumberSubMenu.addCommand(UpdatePhoneNumberCommand.getUpdatePhoneNumberOfPersonCommand());
        phoneNumberSubMenu.addCommand(UpdatePhoneNumberCommand.getUpdatePhoneNumberOfOrganizationCommand());
        phoneNumberSubMenu.addCommand(FindPhoneNumbersBySubscriberCommand.getAddPhoneNumberToPersonCommand());
        phoneNumberSubMenu.addCommand(FindPhoneNumbersBySubscriberCommand.getAddPhoneNumberToOrganizationCommand());
        phoneNumberSubMenu.addCommand(new ViewPhoneNumberListCommand());
        
        //  RealPeriod submenu commands
        periodSubMenu.addCommand(new AddPeriodCommand());
        periodSubMenu.addCommand(new RemovePeriodCommand());
        periodSubMenu.addCommand(new ViewPeriodListCommand());
        
        //  RealPeriod submenu commands
        callSubMenu.addCommand(new AddCallCommand());
        callSubMenu.addCommand(new RemoveCallCommand());
        callSubMenu.addCommand(new ViewCallListCommand());
        
        //  RealPerson submenu commands
        personSubMenu.addCommand(new AddPersonCommand());
        personSubMenu.addCommand(new RemovePersonCommand());
        personSubMenu.addCommand(new UpdatePersonCommand());
        personSubMenu.addCommand(new ViewPersonListCommand());
        
        //  RealOrganization submenu commands
        organizationSubMenu.addCommand(new AddOrganizationCommand());
        organizationSubMenu.addCommand(new RemoveOrganizationCommand());
        organizationSubMenu.addCommand(new UpdateOrganizationCommand());
        organizationSubMenu.addCommand(new ViewOrganizationListCommand());
        
        //  RealAccount submenu commands
        accountSubMenu.addCommand(AddAccountCommand.getAddAccountForPersonCommand());
        accountSubMenu.addCommand(AddAccountCommand.getAddAccountForOrganizationCommand());
        accountSubMenu.addCommand(new RemoveAccountCommand());
        //accountSubMenu.addCommand(new UpdateAccountCommand());
        accountSubMenu.addCommand(FindAccountsBySubscriberCommand.getFindAccountsByPersonCommand());
        accountSubMenu.addCommand(FindAccountsBySubscriberCommand.getFindAccountsByOrganizationCommand());
        accountSubMenu.addCommand(new ViewAccountListCommand()); 
        accountSubMenu.addCommand(new AddMonthlyAccountsCommand());
        
    }


    public static void main(String[] args) throws ParseException, IOException {
        APUS_1 apus = new APUS_1();
//        apus.setFactory(new MemoryDAOFactory());
        apus.setFactory(new JdbcDAOFactory());
        apus.init();
        apus.start();
    }
    
    public void start() {
        while(true) {
          try {  
          currentMenu.execute();
          } catch (BusinessException e) {
              System.out.println(e.getMessage());
          }
          setCurrentMenu(Menu.getCurrentMenu());
        }
    }
    
}
